package com.ytfs.dao;

import com.alibaba.druid.sql.visitor.functions.If;
import com.ytfs.entity.Customer;
import org.hibernate.mapping.Value;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

import java.lang.invoke.VarHandle;
import java.security.spec.NamedParameterSpec;
import java.util.List;


/**
 * @Classname CustomerDao
 * @Description TODO(客户的数据库访问层)
 * @Date 2020/4/29 21:46
 * @Created by ytfs
 * JpaRepository<实体类类型，主键类型>：用来完成基本CRUD操作
 * JpaSpecificationExecutor<实体类类型>：用于复杂查询（分页等查询操作）
 */


public interface CustomerDao extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {

    /**
     * JPQL的方式查询全部客户
     *
     * @return
     */
    @Query(value = "from Customer")
    List<Customer> findAllByJPQL();

    /**
     * 根据客户名称和客户id查询客户
     * jpql： from Customer where custName = ? and custId = ?
     * <p>
     * 对于多个占位符参数
     * 赋值的时候，默认的情况下，占位符的位置需要和方法参数中的位置保持一致
     * <p>
     * 可以指定占位符参数的位置
     * ? 索引的方式，指定此占位的取值来源
     */
    @Query("from Customer where custName = ?2 and custId = ?1")
    Customer findCustomerById(Long custId, String custName);



    /**
     * 使用jpql完成更新操作
     *      案例 ： 根据id更新，客户的名称
     *          更新4号客户的名称，将名称改为“黑马程序员”
     *
     *  sql  ：update cst_customer set cust_name = ? where cust_id = ?
     *  jpql : update Customer set custName = ? where custId = ?
     *
     *  @Query : 代表的是进行查询
     *      * 声明此方法是用来进行更新操作
     *  @Modifying
     *      * 当前执行的是一个更新操作
     *
     */
    @Query("update Customer  set custName = ?1 where custId = ?2")
    @Modifying
    void updateCustomerById(String custName,Long Id);


    /**
     * 使用sql的形式查询：
     *     查询全部的客户
     *  sql ： select * from cst_customer;
     *  Query : 配置sql查询
     *      value ： sql语句
     *      nativeQuery ： 查询方式
     *          true ： sql查询
     *          false：jpql查询 默认值
     *
     */
    @Query(value = "select  * from cst_customer", nativeQuery = true)
    List<Customer> findAllBySql();


    /**
     * 使用sql的形式查询：
     *     条件查询
     *  sql ： select * from cst_customer where cust_name like ?;
     *  Query : 配置sql查询
     *      value ： sql语句
     *      nativeQuery ： 查询方式
     *          true ： sql查询
     *          false：jpql查询 默认值
     *
     */
    @Query(value = "select * from cst_customer where cust_name like ?1", nativeQuery = true)
    Customer FindCustomerByLikeCustName(String custName);
    
    
    /**
     * @author 雨听风说
     * @param 
     * @updateTime 2020/4/30 23:45
     * 方法名的约定：
     *      findBy : 查询
     *            对象中的属性名（首字母大写） ： 查询的条件
     *            CustName
     *            * 默认情况 ： 使用 等于的方式查询
     *                  特殊的查询方式
     *
     *  findByCustName   --   根据客户名称查询
     *
     *  再springdataJpa的运行阶段
     *          会根据方法名称进行解析  findBy    from  xxx(实体类)
     *                                      属性名称      where  custName =
     *
     *      1.findBy  + 属性名称 （根据属性名称进行完成匹配的查询=）
     *      2.findBy  + 属性名称 + “查询方式（Like | isnull）”
     *          findByCustNameLike
     *      3.多条件查询
     *          findBy + 属性名 + “查询方式”   + “多条件的连接符（and|or）”  + 属性名 + “查询方式”
     */


    /**
     * 根据名称精准查询客户
     * @param CustName
     * @return
     */
    Customer findByCustName(String CustName);


    /**
     * 根据客户名称进行模糊查询
     * @param CustName
     * @return
     */
    List<Customer> findByCustNameLike(String CustName);


    /**
     * 根据客户名称模糊查询,并且通过id精确查询
     * @param name
     * @param Id
     * @return
     */
    List<Customer> findByCustNameLikeAndCustId(String name, Long Id);

}
